
package com.scs.application.modules.base.service.impl;

import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.scs.application.core.exceptions.BusinessException;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.thread.BatchSaveTask;
import com.scs.application.core.thread.DefaultSaveHandler;
import com.scs.application.core.utils.*;
import com.scs.application.modules.base.dto.ExcelManufacturerDTO;
import com.scs.application.modules.base.entity.HospitalMaterial;
import com.scs.application.modules.base.entity.Manufacturer;
import com.scs.application.modules.base.entity.Material;
import com.scs.application.modules.base.entity.Supplier;
import com.scs.application.modules.base.mapper.ManufacturerMapper;
import com.scs.application.modules.base.request.ManufacturerQueryRequest;
import com.scs.application.modules.base.service.ManufacturerService;
import com.scs.application.modules.base.service.SingleService;
import com.scs.application.modules.base.service.SupplierService;
import com.scs.application.modules.base.vo.ExcelManufacturerVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.stream.Collectors;


/**
 * 厂商 service 实现
 */
@AllArgsConstructor
@Slf4j
@Service
public class ManufacturerServiceImpl extends BaseServiceImpl<ManufacturerMapper, Manufacturer> implements ManufacturerService {

    private final SupplierService supplierService;

    @Override
    public List<Manufacturer> list(ManufacturerQueryRequest request) {
        List<Manufacturer> list = this.list(getQueryWrapper(request));
        return list;
    }

    @Override
    public IPage<Manufacturer> page(ManufacturerQueryRequest request) {
        if (UserUtils.isSupplier()) {
            request.setSupplierId(UserUtils.getSupplierId());
        }
        IPage page = this.page(request.getPage(), getQueryWrapper(request));
        return page;
    }

    private QueryWrapper<Manufacturer> getQueryWrapper(ManufacturerQueryRequest request) {
        return Wrappers.<Manufacturer>query()
                .eq(StringUtils.isNotBlank(request.getSupplierId()), "supplier_id", request.getSupplierId())
                .like(StringUtils.isNotBlank(request.getName()), "name", request.getName())
                .orderByDesc("gmt_modified");
    }

    /**
     * 同一供应商下，社会信用代码唯一
     *
     * @param entity
     * @return
     */
    @Override
    public boolean add(Manufacturer entity) {
        QueryWrapper<Manufacturer> query = Wrappers.<Manufacturer>query()
                .eq("supplier_id", UserUtils.getSupplierId())
                .ne("id", entity.getId());
        int count = getCount(entity, query);
        return count > 0 ? false : this.saveCascadeById(entity);
    }

    private int getCount(Manufacturer entity, QueryWrapper<Manufacturer> query) {
        // 允许保存空值
        query.and(i -> {
            if (!"".equals(entity.getCompanyCode())) {
                i.eq("company_code", entity.getCompanyCode());
            }
            if (!"".equals(entity.getName())) {
                i.or().eq("name", entity.getName());
            }
            return i;
        });
        return this.count(query);
    }

    @Override
    public boolean update(Manufacturer entity) {
        int count = this.count(Wrappers.<Manufacturer>query()
                .eq("supplier_id", UserUtils.getSupplierId())
                .ne("id", entity.getId())
                .and(i -> i.eq("company_code", entity.getCompanyCode()).or().eq("name", entity.getName()))
        );
        return count > 0 ? false : this.updateCascadeById(entity);
    }

    @Override
    public int countForHospital(ManufacturerQueryRequest request) {
        if (request.getGetHospitalIdByParam() != null && request.getGetHospitalIdByParam() == true) {
            return baseMapper.countForHospital(request.setInactive(HospitalMaterial.ACTIVATE));
        }
        return baseMapper.countForHospital(request.setHospitalId(UserUtils.getHospitalId()).setInactive(HospitalMaterial.ACTIVATE));
    }

    @Override
    public Map<String, String> findByIds(List<String> ids) {
        Collection<Manufacturer> manufacturers = super.listByIds(ids);

        Map<String, String> map = manufacturers.stream().collect(Collectors.toMap(o -> o.getId(), o -> o.getName(), (o1, o2) -> o1));
        return map;
    }

    @Override
    public List<ExcelManufacturerVO> listExcel(ManufacturerQueryRequest request) {
        return this.baseMapper.listExcel(request);
    }

    /**
     * 同一供应商下，社会信用代码唯一
     *
     * @param
     * @return
     */
  /*  @Override
    public boolean saveOrUpdateBatch(Collection<Manufacturer> entityList) {
        if (entityList.size() == 0) {
            return false;
        }
        Set<String> set = entityList.stream().map(o -> o.getCompanyCode()).collect(Collectors.toSet());
        Set<String> nameSet = entityList.stream().map(o -> o.getName()).collect(Collectors.toSet());

        if (nameSet.size() < entityList.size()) {
            throw new BusinessException("存在重复的厂商名称");
        }
        if (set.size() < entityList.size()) {
            throw new BusinessException("存在重复的社会信用代码");
        }

        List<String> existCodeList = this.list(Wrappers.<Manufacturer>query()
                .eq("supplier_id", entityList.stream().findFirst().get().getSupplierId())
        ).stream().map(o -> o.getCompanyCode()).collect(Collectors.toList());

        List<String> existNameList = this.list(Wrappers.<Manufacturer>query()
                .eq("supplier_id", entityList.stream().findFirst().get().getSupplierId())
        ).stream().map(o -> o.getName()).collect(Collectors.toList());

        for (Manufacturer manufacturer : entityList) {
            boolean contains = false;
            boolean nameContains = false;
            if (StringUtils.isBlank(manufacturer.getId())) {
                // 新增
                contains = existCodeList.contains(manufacturer.getCompanyCode());
                nameContains = existNameList.contains(manufacturer.getName());
            } else {
                contains = existCodeList.stream().filter(o -> o.equals(manufacturer.getCompanyCode())).count() > 1;
                nameContains = existNameList.stream().filter(o -> o.equals(manufacturer.getName())).count() > 1;
            }
            if (nameContains) {
                throw new BusinessException("存在重复的厂商名称" + manufacturer.getName());
            }
            if (contains) {
                throw new BusinessException("存在重复的社会信用代码" + manufacturer.getCompanyCode());
            }

        }

        return super.saveOrUpdateBatch(entityList);
    }*/
    @Override
    protected ExcelImportResult doExcelImport(MultipartFile multipartFile, Map<String, Object> params) throws Exception {
        ImportParams importParams = PoiUtils.getDefaultImportParams();
        long currentTimeMillis = System.currentTimeMillis();
        ExcelImportResult importResult = PoiUtils.importExcelMore(multipartFile.getInputStream(), ExcelManufacturerDTO.class, importParams);
        log.info("文件加载耗时：{}", DateUtils.formatTime(System.currentTimeMillis() - currentTimeMillis));

        List<ExcelManufacturerDTO> dtoList = Lists.newArrayList(importResult.getList());

        // 查询出所有供应商
        List<Supplier> supplierList = supplierService.list(Wrappers.<Supplier>query()
                .select("id,name")
        );
        Map<String, Supplier> supplierMap = supplierList.parallelStream().collect(Collectors.toMap(o -> o.getName(), o -> o, (o1, o2) -> o1));
        log.info("加载到{}条供应商数据", supplierMap.size());

        List<String> supplierIdList = supplierList.stream().map(o -> o.getId()).collect(Collectors.toList());
        List<Manufacturer> manufacturerList = this.list(
                Wrappers.<Manufacturer>query()
                        .select("id,name,supplier_id")
                        .in("supplier_id", supplierIdList)
        );
        Map<String, Manufacturer> manufacturerMap = manufacturerList.stream().collect(Collectors.toMap(o -> o.getSupplierId() + o.getName(), o -> o, (o1, o2) -> o1));
        log.info("加载到{}条厂商数据", manufacturerMap.size());


        boolean isSupplier = UserUtils.isSupplier();
        ConcurrentLinkedQueue<Manufacturer> result = new ConcurrentLinkedQueue();

        DefaultSaveHandler<ExcelManufacturerDTO> saveHandler = new DefaultSaveHandler<ExcelManufacturerDTO>() {
            @Override
            public void doSave(int currentIndex, ExcelManufacturerDTO entity) throws BusinessException {
                Manufacturer mf = new Manufacturer();
                BeanUtils.copyProperties(entity, mf);
                String pinyin = PinYinUtils.getAlpha(mf.getName());
                mf.setPinyin(StringUtils.substring(pinyin, 0, 10));

                String supplierName = entity.getSupplierName();
                Supplier supplier = supplierMap.get(supplierName);
//                    Supplier supplier = supplierService.getOne(Wrappers.<Supplier>query().select("id,name").eq("name", supplierName).last("limit 1"));
                if (supplier == null) {
                    importResult.getList().remove(entity);
                    entity.setErrorMsg(String.format("供应商不存在"));
                    importResult.getFailList().add(entity);
                    log.warn("第{}行供应商不存在，请先确认数据是否正确；供应商名称：{}", currentIndex, supplierName);
                    return;
                }
                mf.setSupplierId(supplier.getId());
                Manufacturer manufacturer = manufacturerMap.get(mf.getSupplierId() + mf.getName());
                if (manufacturer != null) {
                    mf.setId(manufacturer.getId());
                    mf.setSupplierId(manufacturer.getSupplierId());
                }
                result.add(mf);

            }
        };
        BatchSaveTask<ExcelManufacturerDTO> task = new BatchSaveTask(saveHandler, dtoList);

        this.forkJoinPool.invoke(task);

        List<Manufacturer> updateManufacturers = result.stream().filter(o -> StringUtils.isNotBlank(o.getId())).collect(Collectors.toList());
        List<Manufacturer> insertManufacturers = result.stream().filter(o -> StringUtils.isBlank(o.getId())).collect(Collectors.toList());
        if (!updateManufacturers.isEmpty()) {
            this.updateBatchById(updateManufacturers);
        }
        if (!insertManufacturers.isEmpty()) {
            //this.saveBatch(insertManufacturers);
            this.baseMapper.insertBatchSomeColumn(Lists.newArrayList(insertManufacturers));
        }
        return importResult;
    }

    @Override
    public boolean removeCascadeBatchByIds(Collection<? extends Serializable> idList) {
        Material findOne = SingleService.inst.materialService.getOne(Wrappers.<Material>query().in("manufacturer_id", idList).last("limit 1"),false);
        if (findOne != null) {
            BusinessException.throwError("厂商[{}]已有相关商品，不允许删除",this.getById(findOne.getManufacturerId()).getName());
        }
        return super.removeCascadeBatchByIds(idList);
    }
}
